package com.lovi.myusercenter.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lovi.myusercenter.common.ErrorCode;
import com.lovi.myusercenter.constant.UserConstant;
import com.lovi.myusercenter.exception.BusinessException;
import com.lovi.myusercenter.service.UserService;
import com.lovi.myusercenter.domain.User;
import com.lovi.myusercenter.mapper.UserMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;



/**
* @author Administrator
* @description 针对表【user】的数据库操作Service实现
* @createDate 2023-08-11 16:50:06
*/
@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
    implements UserService {

    @Resource
    private UserMapper userMapper;

    /**
     * 注册
     * @param userAccount 用户账户，账户名
     * @param password    密码
     * @param checkPassword 确认密码
     * @return 新注册用户的id
     */
    @Override
    public long userRegister(String userAccount , String password, String checkPassword){
        //1.对参数们进行校验
        if(StringUtils.isAnyBlank(userAccount,password,checkPassword)){
            throw new BusinessException(ErrorCode.NULL_ERROR);
        }
        // 特殊字符校验(正则表达式)
        String regEx =  ".*[`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~！@#￥%……&*（）——+|{}【】‘；：”“’。，、？\\\\]+.*";
        if(Pattern.compile(regEx).matcher(userAccount).matches()){
            throw new BusinessException(ErrorCode.PARAM_ERROR,"账户不能有特殊字符");
        }
        if(userAccount.length()<4){
            throw new BusinessException(ErrorCode.PARAM_ERROR,"账号长度不能小于4");
        }
        if(password.length()<8){
            throw new BusinessException(ErrorCode.PARAM_ERROR,"密码长度不能小于8");
        }
        if(!password.equals(checkPassword)){
            throw new BusinessException(ErrorCode.UNIQUE_ERROR);
        }
        //确保用户名的唯一性（去数据库里查询）
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_account",userAccount);
        if(this.count(queryWrapper)>0){
            throw new BusinessException(ErrorCode.UNIQUE_ERROR);
        }

        //2.对密码加密 md5单相加密算法
        String encryptPassword = DigestUtils.md5DigestAsHex((UserConstant.SALT + password).getBytes());


        //3.将注册的信息插入数据库中
        User user = new User();
        user.setUserAccount(userAccount);
        user.setUserPassword(encryptPassword);
        this.save(user);

        return user.getId();
    }

    /**
     * 用户登录实现
     * @param userAccount 用户账号
     * @param password    用户密码
     * @param request     用户请求登录态
     * @return 脱敏后的用户
     */
    @Override
    public User userLogin(String userAccount, String password, HttpServletRequest request) {
        if(StringUtils.isAnyBlank(userAccount,password)){
            throw new BusinessException(ErrorCode.NULL_ERROR);
        }
        //查询数据库的账号和密码
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_account",userAccount);
        //对于password是加密后的
        String encryptPassword = DigestUtils.md5DigestAsHex((UserConstant.SALT + password).getBytes());
        queryWrapper.eq("user_password",encryptPassword);
        User user = userMapper.selectOne(queryWrapper);
        if(user == null){
            log.info("user not match password");
            //用户名或密码错误
            throw new BusinessException(ErrorCode.PARAM_ERROR,"用户名或密码错误");
        }
        //用户信息脱敏
        User safeUser = this.getSafeUser(user);
        //用户信息存到session中（登录态）
        request.getSession().setAttribute(UserConstant.USER_LOGIN_STATE,safeUser);

        return safeUser;
    }

    @Override
    public int userLogOut(HttpServletRequest request) {
        //移除登录态
        request.getSession().removeAttribute(UserConstant.USER_LOGIN_STATE);
        return 1;
    }

    /**
     * 用户信息脱敏
     * @param user 原来的用户
     * @return  脱敏后的用户
     */
    @Override
    public User getSafeUser(User user) {
        if (user == null){
            log.error("User cannot be null");
            throw new BusinessException(ErrorCode.NULL_ERROR,"用户信息为空！");//判空，防止报错
        }
        User safeUser = new User();
        safeUser.setId(user.getId());
        safeUser.setUsername(user.getUsername());
        safeUser.setUserAccount(user.getUserAccount());
        safeUser.setAvatarUrl(user.getAvatarUrl());
        safeUser.setGender(user.getGender());
        safeUser.setPhone(user.getPhone());
        safeUser.setEmail(user.getEmail());
        safeUser.setUserStatus(user.getUserStatus());
        safeUser.setRole(user.getRole());
        safeUser.setCreateTime(user.getCreateTime());
        safeUser.setUpdateTime(user.getUpdateTime());
        safeUser.setIsDelete(user.getIsDelete());
        return safeUser;
    }
    // 这里不用修改false为抛异常是因为controller层对返回结果进行了判断，有false
    @Override
    public boolean hasAdminAuthority(HttpServletRequest request) {
            //先鉴权，
            Object userObj = request.getSession().getAttribute(UserConstant.USER_LOGIN_STATE);
            User user = (User) userObj;
            if(user==null || user.getRole()==UserConstant.COMMON_USER){
                log.info("用户未登录，或用户无权限操作");
                return false;
            }
            if(user.getRole()==UserConstant.ADMIN_USER){
                return true;
            }
            //其他数字也没有权限，只有1是有的嘿嘿
            return false;
    }
    /**
     * 获取所有用户信息
     * @return 脱敏后的用户列表
     */
    @Override
    public List<User> getAllUsers(){
        log.info("测试进入..查询所有用户");
        //因为鉴定权限在controller写了所以这里就先不写了
        ArrayList<User> safeUsers = new ArrayList<User>();
        List<User> users = this.list();
        //脱敏
        for (User user : users) {
            User safeUser = getSafeUser(user);
            safeUsers.add(safeUser);
        }

        return safeUsers;

    }


}

